package org.systemsbiology.bigquery.gae.servlets;

import com.google.api.services.bigquery.model.Job;
import com.google.appengine.api.channel.ChannelMessage;
import com.google.gson.JsonObject;
import org.systemsbiology.bigquery.gae.utils.BQUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;

import static com.google.appengine.api.channel.ChannelServiceFactory.getChannelService;
import static javax.servlet.http.HttpServletResponse.*;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.systemsbiology.bigquery.gae.utils.JobUtils.*;

/**
 * @author hrovira
 */
public class QueryJobStatusChannelTaskServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(QueryJobStatusChannelTaskServlet.class.getName());

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String jobId = request.getParameter("jobId");
        String channelKey = request.getParameter("channelKey");
        log.info("jobId[" + jobId + "]");
        log.info("channelKey[" + channelKey + "]");

        try {
            BQUtils bqutils = new BQUtils();
            Job job = bqutils.lookupJob(jobId);
            if (job == null) {
                // causes task to be retried... should it be?
                response.setStatus(SC_NOT_FOUND);
                return;
            }

            log.info("job=" + job.toPrettyString());
            if (jobIsDone(job)) {
                log.info("job is done");

                JsonObject json = new JsonObject();
                json.addProperty("uri", "/queries/" + jobId);

                String status = "UNKNOWN";
                String message = "query completed";

                if (job.getStatus() != null && !isEmpty(job.getStatus().getState())) {
                    status = job.getStatus().getState();
                }

                if (!isSuccessful(job)) {
                    message = getErrorMessage(job);
                }

                sendMessage(jobId, channelKey, message, status);
            } else {
                sendMessage(jobId, channelKey, "query not done", "RUNNING");

                // causes task to be retried
                response.setStatus(SC_PRECONDITION_FAILED);
            }
        } catch (Exception e) {
            e.printStackTrace(response.getWriter());
            sendMessage(jobId, channelKey, e.toString(), "EXCEPTION");
            log.warning(e.toString());
            response.setStatus(SC_INTERNAL_SERVER_ERROR);
        }
    }

    private void sendMessage(String jobId, String channelKey, String message, String status) {
        log.info("SENDING:" + jobId + "," + channelKey + "," + message + "," + status);

        JsonObject json = new JsonObject();
        json.addProperty("uri", "/queries/" + jobId);
        json.addProperty("message", message);
        json.addProperty("status", status);

        getChannelService().sendMessage(new ChannelMessage(channelKey, json.toString()));

        log.info("SENT:" + jobId + "," + channelKey + "," + message + "," + status);
    }

}
